//////////////////////////////////////////////////////////////////////////

#ifndef _INPUT_H_
#define _INPUT_H_

//////////////////////////////////////////////////////////////////////////

#ifndef _OBSERVABLE_H_
#include "observable.h"
#endif

//////////////////////////////////////////////////////////////////////////

class InputImpl;

//////////////////////////////////////////////////////////////////////////


/** Game input (keyboard and mouse)
*
*  @author   Pasechnik Roman
*  @since    Nov 12th, 2009
*  @updated  Nov 12th, 2009
*/
class Input : public Observable,
              public Observer
{
//////////////////////////////////////////////////////////////////////////

public:

//////////////////////////////////////////////////////////////////////////


    /** Keyboard and mouse keys */
    enum KeyCode
    {
        W,
        S,
        A,
        D,

        MOUSE1,

        EXIT
    };


//////////////////////////////////////////////////////////////////////////


    /** Keyboard and mouse key states */
    enum KeyState
    {
        PRESSED,
        RELEASED
    };


//////////////////////////////////////////////////////////////////////////

    
    /** Input event */
    struct Key
    {
        /** Key code */
        KeyCode m_Code;

        /** It's state */
        KeyState m_State;
    };


//////////////////////////////////////////////////////////////////////////


    /** Mouse position */
    struct MousePosition
    {
        int x;
        int y;
    };


//////////////////////////////////////////////////////////////////////////


    /** Constructor */
    Input();


    /** Destructor */
    virtual ~Input();


//////////////////////////////////////////////////////////////////////////


    /** Process input events */
    void ProcessInput();


    /** Get current key event */
    Key GetKey() const;


    /** Get current mouse position */
    MousePosition GetMousePosition() const;


//////////////////////////////////////////////////////////////////////////

private:

////////////////////////////////////////////////////////////////////////////////
//// Observer interface implementation
////////////////////////////////////////////////////////////////////////////////


    /** Notify observer about event */
    virtual void OnEvent( Event _event, Observable* _observable );


////////////////////////////////////////////////////////////////////////////////


    /** Input impl */
    InputImpl* m_Impl;


//////////////////////////////////////////////////////////////////////////
};


//////////////////////////////////////////////////////////////////////////

#endif

//////////////////////////////////////////////////////////////////////////
